﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ApplLogic.DbToApplConvertor;
using DAL;
using ApplLogic.ApplClasses;
using DAL.Exceptions;
using Entities;

namespace ApplLogic.ApplDbMediators
{
    public class ApplDbResultMediator 
    {
        private DataService m_DataService = DataService.Instance;

        private static volatile ApplDbResultMediator s_Instance = null;
        private static object s_InstanceLockObj = new Object();

        private ApplDbResultMediator() { }

        public static ApplDbResultMediator Instance
        {
            get
            {
                if (s_Instance == null)
                {
                    lock (s_InstanceLockObj)
                    {
                        if (s_Instance == null)
                        {
                            s_Instance = new ApplDbResultMediator();
                        }
                    }
                }

                return s_Instance;
            }
        }


        public bool IsWorkerGotShift(string workerId, DateTime startTime, DateTime endTime)
        {
            return m_DataService.IsWorkerGotShift(workerId, startTime, endTime);
        }

        public void AddResultShiftToWorkerWithStep(ApplSingleResult singleResultToAdd, bool saveChanges = false)
        {
            m_DataService.AddResultShiftToWorker(singleResultToAdd.ApplShift.Id, singleResultToAdd.ApplWorker.PersonalDetails.Id, ApplSingleResult.ConvertEnumTypeToString(singleResultToAdd.Step), saveChanges);
        }

        public void DeleteResult(string workerId, string shiftId, bool saveChanges = false)
        {
            m_DataService.DeleteResult(workerId, shiftId, saveChanges);
        }

        public void UpdateResultType(ApplSingleResult updatedResult, bool saveChanges = false)
        {
            m_DataService.UpdateResultType(updatedResult.ApplWorker.PersonalDetails.Id, updatedResult.ApplShift.Id, 
               ApplSingleResult.ConvertEnumTypeToString(updatedResult.Step), saveChanges);
        }

        public List<ApplShift> GetAllShiftsWorkerGotWithStep(string workerId, eResult resultStep, DateTime startTime, DateTime endTime)
        {
            List<ApplShift> applShifts = new List<ApplShift>();
            foreach (Entities.Shift shift in m_DataService.GetAllShiftsThatWorkerGot(workerId, ApplSingleResult.ConvertEnumTypeToString(resultStep), startTime, endTime))
            {
                applShifts.Add(DbApplObjectConvertor.CreateApplShiftFromDbShift(shift));
            }

            return applShifts;
        }

        public List<ApplShift> GetAllShiftsWorkerGot(string workerId, DateTime startTime, DateTime endTime)
        {
            List<ApplShift> applShifts = new List<ApplShift>();
            foreach (Entities.Shift shift in m_DataService.GetAllShiftsThatWorkerGot(workerId, startTime, endTime))
            {
                applShifts.Add(DbApplObjectConvertor.CreateApplShiftFromDbShift(shift));
            }

            return applShifts;
        }

        public List<ApplWorker> GetAllWorkersThatGotShift(string shiftId, DateTime startTime, DateTime endTime)
        {
            List<ApplWorker> applworkers = new List<ApplWorker>();
            foreach (Entities.Worker worker in m_DataService.GetAllWorkersThatAreRegisteredToShift(shiftId, startTime, endTime))
            {
                applworkers.Add(DbApplObjectConvertor.CreateApplWorkerFromDbWorker(worker));
            }

            return applworkers;
        }

        public List<ApplWorker> GetAllWorkersThatGotShiftWithStep(string shiftId, eResult resultStep, DateTime startTime, DateTime endTime)
        {
            List<ApplWorker> applworkers = new List<ApplWorker>();
            foreach (Entities.Worker worker in m_DataService.GetAllWorkersThatAreRegisteredToShift(shiftId, ApplSingleResult.ConvertEnumTypeToString(resultStep), startTime, endTime))
            {
                applworkers.Add(DbApplObjectConvertor.CreateApplWorkerFromDbWorker(worker));
            }

            return applworkers;
        }

        public Dictionary<ApplWorker, List<ApplSingleResult>> GetAllResultsOfAllWorkers(DateTime startTime, DateTime endTime)
        {
            Dictionary<ApplWorker, List<ApplSingleResult>> allResultsByWorkers = new Dictionary<ApplWorker, List<ApplSingleResult>>();
            foreach (Worker dbWorker in m_DataService.GetAllWorkers())
            {
                ApplWorker applWorker = DbApplObjectConvertor.CreateApplWorkerFromDbWorker(dbWorker);
                List<ApplSingleResult> shiftsOfWorker = new List<ApplSingleResult>();
                foreach (Shift dbShift in m_DataService.GetAllShiftsThatWorkerGot(applWorker.PersonalDetails.Id, startTime, endTime))
                {
                    shiftsOfWorker.Add(new ApplSingleResult()
                                           {
                                               ApplShift = DbApplObjectConvertor.CreateApplShiftFromDbShift(dbShift),
                                               ApplWorker = applWorker,
                                               Step = ApplSingleResult.ConvertStringToEnum(
                                                   m_DataService.GetResultByID(dbWorker.WorkerID, dbShift.ShiftID).Step)
                                           });
                }
                allResultsByWorkers.Add(applWorker, shiftsOfWorker);
            }
            return allResultsByWorkers;
        }

        public Dictionary<ApplWorker, List<ApplShift>> GetAllResultsOfAllWorkersWithResult(eResult result, DateTime startTime, DateTime endTime)
        {
            Dictionary<ApplWorker, List<ApplShift>> allResultsByWorkers = new Dictionary<ApplWorker, List<ApplShift>>();
            foreach (Worker dbWorker in m_DataService.GetAllWorkers())
            {
                ApplWorker applWorker = DbApplObjectConvertor.CreateApplWorkerFromDbWorker(dbWorker);
                List<ApplShift> shiftsOfWorker = new List<ApplShift>();
                foreach (Shift dbShift in m_DataService.GetAllShiftsThatWorkerGot(applWorker.PersonalDetails.Id, 
                    ApplSingleResult.ConvertEnumTypeToString(result), startTime, endTime))
                {
                    shiftsOfWorker.Add(DbApplObjectConvertor.CreateApplShiftFromDbShift(dbShift));
                }
                allResultsByWorkers.Add(applWorker, shiftsOfWorker);
            }
            return allResultsByWorkers;
        }

        public Dictionary<ApplShift, List<ApplSingleResult>> GetAllResultsOfAllShifts(DateTime startTime, DateTime endTime)
        {
            Dictionary<ApplShift, List<ApplSingleResult>> allResultsyShifts = new Dictionary<ApplShift, List<ApplSingleResult>>();
            foreach (Shift dbShift in m_DataService.GetAllShifts())
            {
                ApplShift applShift = DbApplObjectConvertor.CreateApplShiftFromDbShift(dbShift);
                List<ApplSingleResult> workersOfShift = new List<ApplSingleResult>();
                foreach (Worker dbWorker in m_DataService.GetAllWorkersThatAreRegisteredToShift(applShift.Id, startTime, endTime))
                {
                    workersOfShift.Add(new ApplSingleResult()
                    {
                        ApplWorker = DbApplObjectConvertor.CreateApplWorkerFromDbWorker(dbWorker),
                        ApplShift = applShift,
                        Step = ApplSingleResult.ConvertStringToEnum(
                            m_DataService.GetResultByID(dbWorker.WorkerID, dbShift.ShiftID).Step)
                    });
                }
                if(workersOfShift.Count > 0)
                {
                    allResultsyShifts.Add(applShift, workersOfShift);
                }
            }
            return allResultsyShifts;
        }

        public Dictionary<ApplShift, List<ApplSingleResult>> GetAllResultsOfAllShiftsOfWorker(DateTime startTime, DateTime endTime, string workerId)
        {
            Dictionary<ApplShift, List<ApplSingleResult>> allResultsyShifts = new Dictionary<ApplShift, List<ApplSingleResult>>();
            foreach (Shift dbShift in m_DataService.GetAllShifts())
            {
                ApplShift applShift = DbApplObjectConvertor.CreateApplShiftFromDbShift(dbShift);
                List<ApplSingleResult> workersOfShift = new List<ApplSingleResult>();
                foreach (Worker dbWorker in m_DataService.GetAllWorkersThatAreRegisteredToShift(applShift.Id, startTime, endTime))
                {
                    if (dbWorker.WorkerID == workerId)
                    {
                        workersOfShift.Add(new ApplSingleResult()
                                               {
                                                   ApplWorker =
                                                       DbApplObjectConvertor.CreateApplWorkerFromDbWorker(dbWorker),
                                                   ApplShift = applShift,
                                                   Step = ApplSingleResult.ConvertStringToEnum(
                                                       m_DataService.GetResultByID(dbWorker.WorkerID, dbShift.ShiftID).
                                                           Step)
                                               });
                    }
                }
                if (workersOfShift.Count > 0)
                {
                    allResultsyShifts.Add(applShift, workersOfShift);
                }
            }
            return allResultsyShifts;
        }

        public Dictionary<ApplShift, List<ApplWorker>> GetAllResultsOfAllShiftsWithResult(eResult result, DateTime startTime, DateTime endTime)
        {
            Dictionary<ApplShift, List<ApplWorker>> allResultsyShifts = new Dictionary<ApplShift, List<ApplWorker>>();
            foreach (Shift dbShift in m_DataService.GetAllShifts())
            {
                ApplShift applShift = DbApplObjectConvertor.CreateApplShiftFromDbShift(dbShift);
                List<ApplWorker> workersOfShift = new List<ApplWorker>();
                foreach (Worker dbWorker in m_DataService.GetAllWorkersThatAreRegisteredToShift(applShift.Id, 
                   ApplSingleResult.ConvertEnumTypeToString(result), startTime, endTime))
                {
                    workersOfShift.Add(DbApplObjectConvertor.CreateApplWorkerFromDbWorker(dbWorker));
                }
                if (workersOfShift.Count > 0)
                {
                    allResultsyShifts.Add(applShift, workersOfShift);
                }
            }
            return allResultsyShifts;
        }

        public void DeleteAllResultsInTimeRange(DateTime startTime, DateTime endTime, bool saveChanges = false)
        {
            m_DataService.DeleteAllResultsInTimeRange(startTime, endTime, saveChanges);
        
        }

        public void AddResultShiftToWorker(string workerId, DateTime startTime, DateTime endTime, eResult resultType, bool saveChanges = false)
        {
            m_DataService.AddResultShiftToWorker(workerId, startTime, endTime,
                                                 ApplSingleResult.ConvertEnumTypeToString(resultType), saveChanges);
        }

        public void DeleteResult(string workerId, DateTime startTime, DateTime endTime, bool saveChanges = false)
        {
            m_DataService.DeleteResult(workerId, startTime, endTime, saveChanges);
        }
 
        


    }
}
